/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.commands.connection;

import java.util.List;

import org.eclipse.draw2d.geometry.Point;

import com.cea.papyrus.diagraminterchange2.di2.GraphConnector;
import com.cea.papyrus.diagraminterchange2.di2.GraphEdge;

/**
 * Move the end segment attached to an anchor, and all anchors located on this segments.
 * Edge attached to the found anchors are also moved by calling indirectly {@link MoveAnchorPositionAndAttachedEdgesCommand}.
 * Find the end (source or target) and delegate to {@link MoveEdgeSegmentAnchorsCommand}.
 * 
 * @author dumoulin
 */
public class MoveEndSegmentAnchorsCommand {

	/**
	 * Associated edge.
	 */
	GraphEdge edge;
	
	/**
	 * 
	 */
	private MoveEdgeSegmentAnchorsCommand moveSegment;
	
	/**
	 * 
	 */
	private boolean isSourceSegment;
	
	/**
	 * Segment endPoints.
	 */
	private Point p1, p2;
	
	
	/**
	 * Constructor.
	 * 
	 * @param edge the edge to which the segment belong
	 * @param node One extremity of the segment
	 * @param anchor 
	 */
	public MoveEndSegmentAnchorsCommand(GraphConnector anchor, GraphEdge edge) {
		this.edge = edge;
		isSourceSegment = isSourceSegment(anchor, edge);
	}

	/**
	 * Is the anchor the source of the edge ?.
	 * 
	 * @param edge 
	 * @param anchor 
	 * 
	 * @return 
	 */
	protected boolean isSourceSegment(GraphConnector anchor, GraphEdge edge)
	{
		return getEdgeSourceAnchor(edge) == anchor;
	}
	
	/**
	 * 
	 */
	protected void computeSegmentEndPoint()
	{
		
		List<Point> waypoints = edge.getWaypoints();
		if(waypoints != null && waypoints.size() >0)
			{
			if(isSourceSegment) 
			{
				p1 = getEdgeSourceAnchor(edge).getPosition().getCopy();
				p2 = waypoints.get(0).getCopy();
			}
			else // end
			{
				p1 = waypoints.get(waypoints.size()-1).getCopy();
				p2 = getEdgeTargetAnchor(edge).getPosition().getCopy();
			}
		}
		else
		{ // no waypoint
			p1 = getEdgeSourceAnchor(edge).getPosition().getCopy();
			p2 = getEdgeTargetAnchor(edge).getPosition().getCopy();
		}
	}
	
	/**
	 * save the positions of the node.
	 */
	public void savePositions()
	{
		// Find segment endPoints
		computeSegmentEndPoint();
		
		moveSegment = new MoveEdgeSegmentAnchorsCommand(p1, p2, edge.getAnchorage());
//		moveSegment.saveAnchors(p1, p2, edge.getAnchorage());
	}

	/*
	 * Restore the positions of the node.
	 */
	/**
	 * 
	 */
	public void restorePositions()
	{
		moveSegment.restoreAnchors();
	}

	/**
	 * Move the anchor, and all attached edges.
	 * 
	 * @param newPos 
	 * @param anchor 	 */
	public void moveSegment(Point newPos)
	{
		if(isSourceSegment)
		{
			moveSegment.moveSourceEnd(newPos);
		}
		else
		{
			moveSegment.moveTargetEnd(newPos);
		}
	}
	
	/**
	 * Get provided edge source Anchor.
	 * 
	 * @param edge 
	 * 
	 * @return 
	 */
	public GraphConnector getEdgeSourceAnchor(GraphEdge edge)
	{
		return (GraphConnector)edge.getAnchor().get(0);
	}

	/**
	 * Get provided edge target Anchor.
	 * 
	 * @param edge 
	 * 
	 * @return 
	 */
	public GraphConnector getEdgeTargetAnchor(GraphEdge edge)
	{
		return (GraphConnector)edge.getAnchor().get(1);
	}

}